#ifndef _FACE_PROCESS_H_
#define _FACE_PROCESS_H_

#include <stdbool.h>
#include "face_result.h"
#include "net_param.h"
#include "human_pose_type.h"
#include "sl3d.h"
#include "rectify_param.h"

#ifdef __cplusplus
extern "C" {
#endif

extern float FACE_PROC_THRES_DEF_2D;
extern float FACE_PROC_THRES_DEF_3D;
//float FACE_PROC_THRES_DEF_RECOG 0.1733
extern float FACE_PROC_THRES_DEF_RECOG_MASK;
extern float HEAD_POSE_THRES_X;
extern float HEAD_POSE_THRES_Y;

typedef void* TsmHandle;

typedef struct
{
    void *      left;   /*< [in]    */
    void *      right;  /*< [in]    */
    void *      disp;   /*< [out]   */
    void *      depth;  /*< [out]   */
}tsmSl3dData_t;

typedef struct
{
	tsmImg_t	src;
	tsmImg_t	dst;
}tsmResizeData_t;

typedef struct
{
	void* tof;   //in: address of tof
	void* ir;    //out: address of ir
	void* depth; //depth: address of depth
} tsmTofImg_t;

typedef struct grey_img {
    uint8_t* img;
    uint32_t h;
    uint32_t w;
} grey_img_t;

/**
 * @brief Initialization
 * @param face_vec_num: face featrue vector number need be compared to the recognized face featrue vector
 * @param face_vec: the recognized face featrue vector pool
 *          if the length of one feature vector is L, and face_vec_num is N
 *          then the size of face_vec should be N * L * sizeof(int16_t)
 * @param ConvertBoxFun_t : convert face box coordinate for live detection
 */ 
int TSM_ALGO_FaceProcInit(TsmHandle handle, int h, int w,
                    int face_vec_num, int16_t *face_vec , 
                    void * hw3d_param);


/**
 * @brief only detect_vis = true , do fake check
 * @param img_0rgb: 0RGB or 0BGR image, pixel bits is 32, every color is 8 bit
 *           size is h * w * sizeof(uint32_t)
 * @param img_3de: 3de input image, include img_l and img_r
 */ 
TsmFaceResult *TSM_ALGO_FaceProcRun(TsmHandle handle, uint32_t *img_0rgb,
                              TsmSl3dInput *img_3de, void *img_nir,
                                tsmRunMode_t * run_mode);

/*!
* @brief  MUST get paramter before set 
* @return  : 0 = success  
*/
int TSM_ALGO_SetFaceProcessParam(TsmHandle handle, tsmFaceProcessParam * param);

/*!
* @brief  get paramter 
* @return  : 0 = success  
*/
int TSM_ALGO_GetFaceProcessParam(TsmHandle handle, tsmFaceProcessParam * param);


/**
 * @brief register
 * @param face_vec_num: face featrue vector number need be compared to the recognized face featrue vector
 * @param face_vec: the recognized face featrue vector pool
 *          if the length of one feature vector is L, and face_vec_num is N
 *          then the size of face_vec should be N * L * sizeof(int16_t)
 * 
 */ 
TsmFaceResult *TSM_ALGO_FaceProcReg(TsmHandle handle, uint32_t *img_0rgb,
                              TsmSl3dInput *img_3de, void *img_nir,
                              tsmRunMode_t * run_mode);

/**
 * @brief GetFaceLuma
 * @param handle: handler
 * @param img_nir: buffer address of gray image
 * @return luminance (0-255)
 */ 
int TSM_ALGO_GetFaceLuma(TsmHandle handle, void *img_nir);

/**
 * @brief GetFaceLumaRoi
 * @param handle: handler
 * @param img_nir: buffer address of gray image
 * @param box    : face box
 * @return luminance (0-255)
 */ 
int TSM_ALGO_GetFaceLumaRoi(TsmHandle handle, void *img_nir, TsmFaceBox* box);


/**
 * @brief match
 * @param match_param: Parameter data for matching
 * @return  match result
 */ 
TsmMatchResult *TSM_ALGO_RunAmrMatch(tsmMatchParam *match_param);


/**
 * @brief resize 
 * @param src: h:hight w: width bits: bit width(just support 8bits and 32bits) 
 * @param dst: such as src
 * @return  error code
 */ 
int TSM_ALGO_RunAmrResize(tsmImg_t* src, tsmImg_t* dst);

/**
 * @brief single eye init
 * @param data: sl3d config data
 * @return  error code
 */ 
int TSM_ALGO_InitSl3dDepth_SingleEye(tsmTRP_Sl3dCfg_t* data);

/**
 * @brief single eye run
 * @param data: include param in and param out
 * @return  error code
 */ 
int TSM_ALGO_RunSl3dDepth_SingleEye(tsmTRP_Sl3dData_t* data);

int TSM_ALGO_InitSl3dDepth_doubleIR(tsmTRP_Sl3dCfg_t* data);
int TSM_ALGO_RunSl3dDepth_doubleIR(tsmTRP_Sl3dData_t* data);

/**
 * @brief tof tansfer to ir and depth
 * @param data: include param in and param out
 * @return  error code
 */
int TSM_TOF_GetIrDepth(tsmTofImg_t* data);

/**
 * @brief Depth Stream Init
 * @return  error code
 */ 
int TSM_ALGO_RunSl3dDepthStreamInit(void);

/**
 * @brief 
 * @param data: include param in and param out,ck804 manage the memory of depthmap
 * @return  error code
 */ 
int TSM_ALGO_RunSl3dDepthStreamIn(tsmTRP_Sl3dData_t* data);

/**
 * @brief get result
 * @param result: the address of depthmap
 * @return  error code
 */ 
int TSM_ALGO_RunSl3dDepthStreamOut(tsmTRP_Sl3dRet_t* result);

/*!
* @brief:
* @return : version
*/
char *TSM_ALGO_GetVersion(TsmHandle handle);

int TSM_ALGO_InitSl3dDepthcompenSingleEye(tsmTRP_Sl3dCfg_t* data);


/**
 * @brief Initialization
 * @param handle : handler
 * @param h : height of image
 * @param w : width of immage
 * @return  error code
 */
int TSM_ALGO_HumanPoseInit(TsmHandle handle, int h, int w);

/**
 * @brief human pose detect
 * @param handle : handler
 * @param img_0rgb : image
 * @param param : paramers
 * @return  result 
 */
struct tsmPoseResult *TSM_ALGO_HumanPoseDetect(TsmHandle handle, uint32_t *img_0rgb,tsmDeviceParam *param);

/**
 * @brief   grey image binaryzation 
 * @param in  : input image information
 * @param out : out->h and out->w must set,  out->img is the return address 
 * @return  error code 
 */
int TSM_ALGO_ImageBina(grey_img_t *in , grey_img_t* out);

#define AFFINE_ROTATE_RIGHT90   0
#define AFFINE_ROTATE_LEFT90    1
/**
 * @brief resize 
 * @param src: h:hight w: width bits: bit width(just support 8bits and 32bits) 
 * @param dst: such as src
 * @param rotate: 0 : turn right for 90
 *                1 : turn left for 90
 * @return  error code
 */ 
int TSM_ALGO_RunAmrRotate90(tsmImg_t* src, tsmImg_t* dst, uint8_t rotate);


algo_rectify_output_t *TSM_ALGO_CalibOnLineRun(TsmHandle handle, int h, int w, float baseline, float focus, void *img_l, RectifyPoint *l,
                              void *img_r, RectifyPoint *r);

void tsm_algo_set_805_log_level(uint8_t level);
#ifdef __cplusplus
}
#endif

#endif

